﻿using GGetTestService.Repository;
using GGetTestService.Repository.UnitOfWork;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace GGetTestService.Services.Base
{
    public class BaseService<TEntity> : IBaseService<TEntity> where TEntity : class
    {
        private readonly IUnitOfWork _unitOfWork;
        private IRepository<TEntity> _repository;

        public BaseService(IUnitOfWork unitOfWork)
        {
            _unitOfWork = unitOfWork;
            _repository = _unitOfWork.GetRepository<TEntity>();
        }

        public async Task AddAsync(TEntity entity)
        {
            await _repository.AddAsync(entity);
            await _unitOfWork.SaveChangesAsync();
        }

        public async Task AddRangeAsync(IList<TEntity> list)
        {
            await _repository.AddRangeAsync(list);
            await _unitOfWork.SaveChangesAsync();
        }

        public async Task<int> CountAsync(Expression<Func<TEntity, bool>> predicate)
        {
            return await _repository.CountAsync(predicate);
        }

        public async Task<bool> ExistAsync(Expression<Func<TEntity, bool>> predicate)
        {
            return await _repository.ExistAsync(predicate);
        }

        public async Task<IEnumerable<TEntity>> GetAllListAsync()
        {
            return await _repository.GetAllListAsync();
        }

        public async Task<IEnumerable<TEntity>> GetAllListWithNoTrackingAsync()
        {
            return await _repository.GetAllListWithNoTrackingAsync();
        }

        public async Task<IEnumerable<TEntity>> GetListAsync(IQueryable<TEntity> queryable)
        {
            return await _repository.GetListAsync(queryable);
        }

        public async Task<IEnumerable<TEntity>> GetListAsync(Expression<Func<TEntity, bool>> expression)
        {
            return await _repository.GetListAsync(expression);
        }

        public async Task<IEnumerable<TEntity>> GetListWithNoTrackingAsync(IQueryable<TEntity> queryable)
        {
            return await _repository.GetListWithNoTrackingAsync(queryable);
        }

        public async Task<IEnumerable<TEntity>> GetListWithNoTrackingAsync(IQueryable<TEntity> queryable, int page, int pageSize)
        {
            return await _repository.GetListWithNoTrackingAsync(queryable, page, pageSize);
        }

        public async Task<IEnumerable<TEntity>> GetListWithNoTrackingAsync(Expression<Func<TEntity, bool>> expression)
        {
            return await _repository.GetListWithNoTrackingAsync(expression);
        }

        public async Task<IEnumerable<TEntity>> GetListWithNoTrackingAsync(Expression<Func<TEntity, bool>> expression, int page, int pageSize)
        {
            return await _repository.GetListWithNoTrackingAsync(expression);
        }

        public async Task<TEntity> GetModelAsync(Expression<Func<TEntity, bool>> predicate)
        {
            return await _repository.GetModelAsync(predicate);
        }

        public async Task<TEntity> GetModelByIdAsync(object id)
        {
            return await _repository.GetModelByIdAsync(id);
        }

        public async Task RemoveAsync(TEntity entity)
        {
            _repository.Remove(entity);
            await _unitOfWork.SaveChangesAsync();
        }

        public async Task RemoveRangeAsync(IList<TEntity> list)
        {
            _repository.RemoveRange(list);
            await _unitOfWork.SaveChangesAsync();
        }

        public async Task UpdateAsync(TEntity entity)
        {
            _repository.Update(entity);
            await _unitOfWork.SaveChangesAsync();
        }

        public async Task UpdateRangeAsync(IList<TEntity> list)
        {
            _repository.UpdateRange(list);
            await _unitOfWork.SaveChangesAsync();
        }

        public async Task<int> SaveChangesAsync()
        {
            return await _unitOfWork.SaveChangesAsync();
        }
    }
}